/*
 *  @product.title@
 *  Copyright (C) @product.copyright-year@
 *    @product.vendor@
 *    Registration Number: @product.registration-number@
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package jp.go.aist.six.util.net;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;



/**
 * An HTTP Communication helper class.
 *
 * @author  Akihito Nakamura, AIST
 * @version $Id: Http.java 297 2011-02-21 08:25:52Z nakamura5akihito $
 */
public class Http
{

    /**
     * Logger.
     */
    private static final Logger  _LOG_ =
        LoggerFactory.getLogger( Http.class );



    private static final List<MediaType>  _DEFAULT_ACCEPT_MEDIA_TYPES_ =
        Arrays.asList( new MediaType[] {
                        MediaType.ALL
//                        MediaType.TEXT_XML, MediaType.APPLICATION_XML
                        } );



    /**
     * Constructor.
     */
    public Http()
    {
    }



    /**
     */
    protected RestTemplate _getRestTemplate()
    {
        return (new RestTemplate());
    }



    /**
     * GET
     */
    public void getTo(
                    final URL location,
                    final File file
                    )
    throws HttpException
    {
        getTo( location, file, _DEFAULT_ACCEPT_MEDIA_TYPES_ );
    }



    /**
     * GET
     */
    public void getTo(
                    final URL location,
                    final File file,
                    final List<MediaType> acceptMediaTypes
                    )
    throws HttpException
    {
        _LOG_.debug( "HTTP GET: URL=" + location
                        + ", output file=" + file );

        URI  uri = null;
        try {
            uri = location.toURI();
                           //throws URISyntaxException
        } catch (URISyntaxException ex) {
            throw new HttpException( ex );
        }

        RestTemplate  rest = _getRestTemplate();
        try {
            FileResponseExtractor  extractor = new FileResponseExtractor( file );
            AcceptHeaderRequestCallback  callback =
                new AcceptHeaderRequestCallback( acceptMediaTypes );
            rest.execute(
                            uri,
                            HttpMethod.GET,
                            callback,
                            extractor
                            );
        } catch (RestClientException ex) {
            _LOG_.error( "HTTP GET error: " + ex );
            throw new HttpException( ex );
        }
    }



    /**
     * REST: POST
     */
    public void postFrom(
                    final URL location,
                    final File file,
                    final MediaType mediaType
                    )
    throws HttpException
    {
        _LOG_.debug( "HTTP POST: URL=" + location
                        + ", output file=" + file );

        URI  uri = null;
        try {
            uri = location.toURI();
                      //throws URISyntaxException
        } catch (URISyntaxException ex) {
            throw new HttpException( ex );
        }

        RestTemplate  rest = _getRestTemplate();
        try {
            FileRequestCallback  callback =
                new FileRequestCallback( file, mediaType );
            rest.execute(
                            uri,
                            HttpMethod.POST,
                            callback,
                            null
                            );
        } catch (RestClientException ex) {
            _LOG_.error( "HTTP POST error: " + ex );
            throw new HttpException( ex );
        }
    }



    /**
     * A simple callback for the Spring RestTemplate.
     */
    private static class AcceptHeaderRequestCallback
    implements RequestCallback
    {

        private final List<MediaType>  _accept;



        private AcceptHeaderRequestCallback(
                        final List<MediaType> accept
                        )
        {
            _accept = accept;
        }



        @Override
        public void doWithRequest(
                        final ClientHttpRequest request
                        )
        throws IOException
        {
            request.getHeaders().setAccept( _accept );
        }
    }

}
// OvalInterpreter

